﻿#include "CWorkMngAutoHy.h"
#include "CLogOper.h"
#include "CAlgorithmContext.h"
#include "CThreadBase.h"
#include "CSqlOper.h"
CWorkMngAutoHy::CWorkMngAutoHy()
{
	initEvent(9);                       //初始化事件数量
	m_nDisConnectPlcCount = 0;
	m_bBeltAWork = false;
	m_bBeltBWork = false;
	m_nBeltWorkCount = 0;
	m_pRptInterface = nullptr;
}

CWorkMngAutoHy::~CWorkMngAutoHy()
{
	endWork();
	if (m_pRptInterface)
	{
		delete m_pRptInterface;
		m_pRptInterface = nullptr;
	}
}

void CWorkMngAutoHy::startWork()
{
	ThreadBegin();
}

void CWorkMngAutoHy::endWork()
{
	ThreadStop();
}

/********************************************************************************
*Description:
*FunParameter:nType 1执行任务  2 暂停任务 3 中止任务  4 恢复任务
*FunReturnValue:
*Author:Gaojia
*Date:2024/03/20
*ChangeDate:
*Modifier:
*ModifyReason:
*Version:V1.0.0
********************************************************************************/
void CWorkMngAutoHy::execEvent(int nType)
{
	//复位所有事件
	resetEvent();
	switch (nType)
	{
	case 2:
		//2 暂停任务
		setEvent(enSUSPENDTASK);
		break;
	case 3:
		//3 中止任务
		setEvent(enEXECENDTASK);
		break;
	case 4:
		setEvent(enRESETTASK);
		//4 恢复任务
		break;
	default:
		break;
	}
}

void CWorkMngAutoHy::init(QString sGuid, CDevBase * pIFDev, CRBaseData * pRBasicData)
{
	m_sGuid = sGuid;
	m_pRobDev = pIFDev;
	m_pRBasicDataNd = (CRBaseData *)pRBasicData;
	m_pAlgorithmContext = new CAlgorithmContext(m_sGuid);
	m_pAlgorithmContext->init(m_pRobDev, m_pRBasicDataNd);
	m_sDevName = m_pRobDev->m_pDevDataBase->m_sRobName;
}

void CWorkMngAutoHy::taskSuspend()
{
	//执行任务状态  0空闲  1任务执行中 2任务暂停中
	if (m_pRBasicDataNd->m_nTaskExecStatus == 1)
	{
		m_pRBasicDataNd->m_nTaskExecStatus = 2;
	}
	else if (m_pRBasicDataNd->m_nTaskExecStatus == 2)
	{

	}
	else//无任务 继续执行扫描线程
	{
		setEvent(enSCANTASK);
	}
}

void CWorkMngAutoHy::taskStop()
{
	m_pRBasicDataNd->m_nTaskExecStatus = 0;
	/**
	* @ Author: Gaojia
	* @ Description: 任务一些数据赋值
	*/
	m_pRBasicDataNd->m_pMutex->lock();
	//获取结束电量
	CDevDataBase* pDevDataRob = (CDevDataBase*)m_pRobDev->m_pDevDataBase;
	double dEndPower = pDevDataRob->m_sRobBatteryInfo.toDouble();
	m_pRBasicDataNd->m_pTaskExecInfo->m_dEndPower = dEndPower;//结束电量
	m_pRBasicDataNd->m_pTaskExecInfo->m_sEndTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");


	QString strCommentTemp = "";//任务最后执行描述
	//首先判断当前的任务是否是正常结束的
	if (m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount < m_pRBasicDataNd->m_pTaskExecInfo->m_nItemCount)
	{
		double dProcess = (((double)m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount) / ((double)m_pRBasicDataNd->m_pTaskExecInfo->m_nItemCount)) * 100;
		int nCurrentProgress = (int)dProcess;
		//根据PLC反馈填写异常原因
		QString sErr = "";
		if (pDevDataRob->m_bPlcConnectState == false)
		{
			sErr = A2T("与PLC连接断开,主动中止任务");
		}
		else
		{
			int nTaskErr = pDevDataRob->m_sTaskErr.toInt();
			if (nTaskErr == 0)
			{
				sErr = A2T(" 正常结束");
			}
			else if (nTaskErr == 1)
			{
				sErr = A2T(" 电量不足拒绝任务");
			}
			else if (nTaskErr == 2)
			{
				sErr = A2T(" 任务期间强制充电");
			}
			else if (nTaskErr == 3)
			{
				sErr = A2T(" 待命期间启动充电");
			}
			else if (nTaskErr == 4)
			{
				sErr = A2T(" 待命时间超过3分钟启动充电");
			}
			else
			{
				sErr = A2T(" 其他原因");
			}
		}

		m_pRBasicDataNd->m_pTaskExecInfo->m_sTaskBreakReason += sErr;
		strCommentTemp = A2T("任务进度[%1%] %2").arg(nCurrentProgress).arg(m_pRBasicDataNd->m_pTaskExecInfo->m_sTaskBreakReason);
		m_pRBasicDataNd->m_pTaskExecInfo->m_sTaskExecDes = A2T("未完成");
		m_pRBasicDataNd->m_pTaskExecInfo->m_nExecState = 3;//任务终止
		//添加日志
		SExecLog sLog;
		sLog.m_nAlarmLevel = enWorkInfo;
		sLog.m_sDescriptionl = strCommentTemp;
		sLog.m_sFuncName = A2T("任务");
		CLogOper::instance().addMsg(sLog, m_sGuid);
	}
	else
	{
		strCommentTemp = A2T("任务执行成功");
		m_pRBasicDataNd->m_pTaskExecInfo->m_sTaskExecDes = A2T("已完成");
		m_pRBasicDataNd->m_pTaskExecInfo->m_nExecState = 1;//任务已执行
		//添加日志
		SExecLog sLog;
		sLog.m_nAlarmLevel = enWorkInfo;
		sLog.m_sDescriptionl = strCommentTemp;
		sLog.m_sFuncName = A2T("任务");
		CLogOper::instance().addMsg(sLog, m_sGuid);
	}
	m_pRBasicDataNd->m_pMutex->unlock();
	//updateTaskExecInfo(m_pRBasicDataNd->m_pTaskExecInfo);//更新任务执行记录


	//==============pdf报表输出模块================
	m_pRBasicDataNd->m_pMutex->lock();
	if (m_pRptInterface == nullptr)
	{
		m_pRptInterface = new CPdfRptInterface(m_pRBasicDataNd->m_nSmallSceneType);//new pdf报表接口类
	}
	QString sRobName = pDevDataRob->m_sRobName;//机器人名称
	QString sPdfFolderPath = CPublicData::instance().m_sPdfOutputPath;//输出文件夹(取xml中配置的)
	QString sClientCpyName = CPublicData::instance().m_sCustomName;//客户电厂名称(取xml中配置的)
	QString sHttpPrefix = CPublicData::instance().m_sHttpUrl;//http路径前缀(取xml中配置的)
	//new 新的任务执行数据(去深拷贝一份数据)
	CTaskExecInfo *pTaskExecCopy = new CTaskExecInfo();
	m_pRBasicDataNd->m_pTaskExecInfo->deepCopyData(pTaskExecCopy);
	m_pRBasicDataNd->m_pMutex->unlock();//拷贝完解锁
	m_pRptInterface->expSingleRobPdfRpt(pTaskExecCopy, sRobName, sPdfFolderPath, sHttpPrefix, sClientCpyName);//接口类->导出所有报表
	updateTaskExecInfo(pTaskExecCopy);//更新任务执行记录
	//delete 新的任务执行数据
	pTaskExecCopy->deleteDeepCopyData();//释放深拷贝数据

	setEvent(enSCANTASK);
}

void CWorkMngAutoHy::taskReset()
{
	//执行任务状态  0空闲  1任务执行中 2任务暂停中
	if (m_pRBasicDataNd->m_nTaskExecStatus == 1)
	{
		setEvent(enJUDGE);
	}
	else if (m_pRBasicDataNd->m_nTaskExecStatus == 2)
	{
		m_pRBasicDataNd->m_nTaskExecStatus = 1;
		if (m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount > 0)
		{
			//从上一个巡检项执行
			m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount--;
		}
		setEvent(enJUDGE);
	}
	else //无任务 继续执行扫描线程
	{
		setEvent(enSCANTASK);
	}
}

/********************************************************************************
*Description: 查询数据库里面的任务信息 并生成任务
*FunParameter:
*FunReturnValue:
*Author:Gaojia
*Date:2024/03/18
*ChangeDate:
*Modifier:
*ModifyReason:
*Version:V1.0.0
********************************************************************************/
void CWorkMngAutoHy::taskScan()
{
	resetEvent(enSCANTASK);
	//如果没有任务直接返回
	if (m_vecTaskInfo.size() <= 0)
	{
		setEvent(enSCANTASK);
		return;
	}
	bool bAct = false;
	for (int i = 0; i < m_vecTaskInfo.size(); i++)
	{
		if (isTaskExec(m_vecTaskInfo[i].m_sTaskActTime))
		{
			m_cTaskInfo = m_vecTaskInfo[i];
			m_vecTaskInfo.remove(i);
			bAct = true;
			break;
		}
	}

	if (bAct)
	{
		taskInit();
	}
	else
	{
		setEvent(enSCANTASK);
	}
}

void CWorkMngAutoHy::taskInit()
{
	QString sErrMsg = "";
	//1.判断设备状态
	{
		/*setEvent(enSLEEP);
		return;*/
	}
	//2.获取模板信息
	QString sTemplateFixedID = m_cTaskInfo.m_sTemplateFixedID;
	CTemplateInfo cTemplateInfo = selectTemplateInfo(sTemplateFixedID, sErrMsg);
	if (cTemplateInfo.m_sTemplateFixedID == "")
	{
		//模板不存在
		SExecLog sLog;
		sLog.m_nAlarmLevel = enSysAlarm;
		sLog.m_sDescriptionl = A2T("初始化任务时模版不存在");
		sLog.m_sFuncName = A2T("任务");
		CLogOper::instance().addMsg(sLog, m_sGuid);
		return;
	}
	//3.创建执行任务
	m_pRBasicDataNd->m_pMutex->lock();
	CTaskExecInfo *pTaskExecInfo = m_pRBasicDataNd->m_pTaskExecInfo;
	CDevDataBase* pDevData = (CDevDataBase*)m_pRobDev->m_pDevDataBase;
	pDevData->m_pMutex->lock();
	pTaskExecInfo->createTaskInfo(m_pRBasicDataNd->m_pPolArea, m_cTaskInfo, cTemplateInfo, pDevData->m_sRobBatteryInfo.toInt(), m_pRBasicDataNd->m_nRobType);
	pDevData->m_pMutex->unlock();
	m_pRBasicDataNd->m_pMutex->unlock();
	//5.如果没有巡检项 跳转扫描任务
	if (pTaskExecInfo->m_nItemCount == 0)
	{
		setEvent(enSCANTASK);
	}
	else
	{
		if (!pDevData->m_pDevDataCam->m_cMapCamerInfo[enIR].m_bConStatus)
		{
			SCtrInfo cCtrInfo;
			cCtrInfo.m_sGuid = m_sGuid;
			cCtrInfo.m_nSubCtrDevType = enIR;
			cCtrInfo.m_bCtrSync = true;
			cCtrInfo.m_bHasCtr = false;
			cCtrInfo.m_hHwnd = NULL;
			cCtrInfo.m_nCtrDevType = enSubDev1;
			cCtrInfo.m_nCtrCmd = enCRealPlay;
			if (!m_pRobDev->ctrDev(cCtrInfo))
			{
				SExecLog sLog;
				sLog.m_nAlarmLevel = enProcessAlarm;
				sLog.m_sDescriptionl = A2T("任务下发失败,原因SDK无句柄预览失败");
				sLog.m_sFuncName = A2T("任务");
				CLogOper::instance().addMsg(sLog, m_sGuid);
				setEvent(enSCANTASK);
				return;
			}
		}


		//setEvent(enJUDGE);     //20240719

		SCtrInfo cCtrInfo;
		cCtrInfo.m_sGuid = m_sGuid;
		cCtrInfo.m_bCtrSync = true;
		cCtrInfo.m_bHasCtr = false;
		cCtrInfo.m_vecArray = pTaskExecInfo->m_vecTaskArray;
		cCtrInfo.m_vecIndex = pTaskExecInfo->m_vecTaskIndex;
		cCtrInfo.m_nCtrDevType = enOntology;
		cCtrInfo.m_nCtrCmd = enCExecTask;
		if (m_pRobDev->ctrDev(cCtrInfo))
		{
			//4.数据添加到数据库  
			m_pRBasicDataNd->m_pMutex->lock();
			CTaskExecInfo *pTaskExecInfo = m_pRBasicDataNd->m_pTaskExecInfo;
			pTaskExecInfo->m_nExecState = 2;
			insertTaskExecInfo(pTaskExecInfo);
			m_pRobDev->m_pDevDataBase->m_bTaskExec = true;
			m_pRBasicDataNd->m_pMutex->unlock();
			//记录日志
			SExecLog sLog;
			sLog.m_nAlarmLevel = enWorkInfo;
			sLog.m_sDescriptionl = A2T("任务下发PLC成功");
			sLog.m_sFuncName = A2T("任务");
			CLogOper::instance().addMsg(sLog, m_sGuid);
			setEvent(enJUDGE);
			/**
			* @ Author: Gaojia
			* @ Description: 获取光字牌报警关联Id
			*/
		/*	QMap<QString, QString>mapCorreId = GetCorreGuid(m_pRobDev->m_sDevGuid, 0);
			m_pRBasicDataNd->m_pMutex->lock();
			m_pRBasicDataNd->m_pTaskExecInfo->m_mapCorreId = mapCorreId;
			m_pRBasicDataNd->m_pMutex->unlock();*/
			sysSleepTime(2000);
		}
		else
		{
			//记录日志
			SExecLog sLog;
			sLog.m_nAlarmLevel = enProcessAlarm;
			sLog.m_sDescriptionl = A2T("任务下发PLC失败");
			sLog.m_sFuncName = A2T("任务");
			CLogOper::instance().addMsg(sLog, m_sGuid);
			setEvent(enSCANTASK);
		}
	}
}

void CWorkMngAutoHy::taskJudge()
{
	//m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount = 6;
	//execAlgorithm();//调用算法处理
	//1.异常判断

	//2.根据机器人工作状态 跳转对应流程
	CDevDataBase *pDevDataRob = (CDevDataBase *)m_pRobDev->m_pDevDataBase;
	if (pDevDataRob->m_bPlcConnectState == false)//PLC连接异常，跳转判断线程
	{
		if (m_nDisConnectPlcCount < 36000)//30分钟内继续跳转判断流程
		{
			setEvent(enJUDGE);
			m_nDisConnectPlcCount++;
			return;
		}
		else//30分钟还是与PLC断连，则跳转结束流程
		{

			setEvent(enEXECENDTASK);
			//记录日志
			SExecLog sLog;
			sLog.m_nAlarmLevel = enProcessAlarm;
			sLog.m_sDescriptionl = A2T("由于通讯异常持续30min,软件主动中止任务");
			sLog.m_sFuncName = A2T("任务");
			CLogOper::instance().addMsg(sLog, m_sGuid);
			m_nDisConnectPlcCount = 0;
			return;
		}
	}
	else
	{
		m_nDisConnectPlcCount = 0;
	}

	if (m_bBeltAWork || m_bBeltBWork)
	{
		if (m_cTaskInfo.m_nTaskType != 3 && m_cTaskInfo.m_nTaskType != 4)
		{
			SCtrInfo cCtrInfo;
			cCtrInfo.m_sGuid = m_sGuid;
			cCtrInfo.m_bCtrSync = true;
			cCtrInfo.m_bHasCtr = false;
			cCtrInfo.m_nCtrDevType = enOntology;
			cCtrInfo.m_nCtrCmd = enCAbortTask;
			m_pRobDev->ctrDev(cCtrInfo);

			setEvent(enEXECENDTASK);
			//记录日志
			SExecLog sLog;
			sLog.m_nAlarmLevel = enProcessAlarm;
			if (m_bBeltAWork)
			{
				sLog.m_sDescriptionl = A2T("A侧皮带运行中止当前任务");
			}
			else
			{
				sLog.m_sDescriptionl = A2T("B侧皮带运行中止当前任务");
			}
			sLog.m_sFuncName = A2T("任务");
			CLogOper::instance().addMsg(sLog, m_sGuid);
			m_nDisConnectPlcCount = 0;
			return;
		}
	}
	int nState =pDevDataRob->m_nTaskStatus;
	int nItemState = pDevDataRob->m_nPolItemExecStatus;
	int nItemIndex = pDevDataRob->m_nPolItemNum - 1;
	if (pDevDataRob->m_bTaskExec == false)
	{
		nState = 3;
	}
	switch (nState)
	{
	case 0:    //空闲  跳转结束任务流程
	{
		setEvent(enEXECENDTASK);
		//记录日志
		SExecLog sLog;
		sLog.m_nAlarmLevel = enProcessAlarm;
		sLog.m_sDescriptionl = A2T("读取到的任务状态为0");
		sLog.m_sFuncName = A2T("任务");
		CLogOper::instance().addMsg(sLog, m_sGuid);
	}
	break;
	case 1:   //任务执行中 跳转判断任务执行
	{
		m_pRBasicDataNd->m_pMutex->lock();
		CTaskExecInfo *pTaskExecInfo = m_pRBasicDataNd->m_pTaskExecInfo;
		int nItemIndexCurr = pTaskExecInfo->m_mapCorrIndex[nItemIndex];
		if (pTaskExecInfo->m_nExecItemCount <= nItemIndexCurr)
		{
			if (nItemState == 2)
			{
				int nItemIndexLast = 0;
				if (nItemIndex > 0)
				{
					nItemIndexLast = pTaskExecInfo->m_mapCorrIndex[nItemIndex - 1] + 1;
				}
				if (pTaskExecInfo->m_nExecItemCount < nItemIndexLast)
				{
					pTaskExecInfo->m_nExecItemCount = nItemIndexLast;
				}
				setEvent(enPROCESS);         //判断执行到新的巡检项 跳转执行任务流程
			}
			else
			{
				setEvent(enJUDGE);       //  跳转判断线程
			}
		}
		else
		{
			if (nItemIndexCurr < pTaskExecInfo->m_nItemCount - 1)
			{
				setEvent(enJUDGE);       //判断PLC没有执行到新的巡检项  跳转判断线程
			}
			else
			{
				setEvent(enEXECENDTASK); //巡检项执行超过巡检项总数  跳转结束线程
			}
		}
		m_pRBasicDataNd->m_pMutex->unlock();
	}
	break;
	case 2:  //任务暂停中 跳转判断线程
	{
		setEvent(enJUDGE);
	}
	break;
	case 3:   //任务异常中止 跳转结束任务流程
	{
		//记录日志
		SExecLog sLog;
		sLog.m_nAlarmLevel = enProcessAlarm;
		sLog.m_sDescriptionl = A2T("读取到的任务状态为3");
		sLog.m_sFuncName = A2T("任务");
		CLogOper::instance().addMsg(sLog, m_sGuid);
		setEvent(enEXECENDTASK);
	}
	break;
	case 4:   //任务中止 临时修改  后期是0结束任务   
	{
		//记录日志
		SExecLog sLog;
		sLog.m_nAlarmLevel = enProcessAlarm;
		sLog.m_sDescriptionl = A2T("读取到的任务状态为4");
		sLog.m_sFuncName = A2T("任务");
		CLogOper::instance().addMsg(sLog, m_sGuid);
		setEvent(enEXECENDTASK);
	}
	break;
	default:
	{
		setEvent(enJUDGE);
	}
	break;
	}
}

void CWorkMngAutoHy::taskExceptoin()
{
	m_pRBasicDataNd->m_pMutex->lock();
	//标志位置为任务暂停中	
	m_pRBasicDataNd->m_nTaskExecStatus = 2;
	//判断设备状态
	if (1)
	{
		setEvent(enRESETTASK);
	}
	else
	{
		setEvent(enEXCEPTION);
	}
	m_pRBasicDataNd->m_pMutex->unlock();
}

void CWorkMngAutoHy::taskProcess()
{
	m_pRBasicDataNd->m_pMutex->lock();
	if (m_pRBasicDataNd->m_pTaskExecInfo->m_vecPolItemCom[m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount]->m_pPolItem->m_nDevType == 1)//当前需要执行的巡检项为云台巡检项
	{
		m_pRBasicDataNd->m_pMutex->unlock();  //gj修改
		//hjx++延时几秒，为了海康专家模式下需要一段时间才开始正确的温度
		sysSleepTime(2000);
	}
	else
	{
		m_pRBasicDataNd->m_pMutex->unlock();
	}
	/**
	* @ Author: Gaojia
	* @ Description: 1.执行巡检项
	*/
	if (!execItem())
	{
		setEvent(enEXCEPTION);
		return;
	}

	/**
	* @ Author: WeiXIaoYU
	* @ Description:  2.算法处理
	*/
	execAlgorithm();//调用算法处理

	/**
	* @ Author: Gaojia
	* @ Description:
	*/
	//upAlarmInfo();
	m_pRBasicDataNd->m_pMutex->lock();
	CDevDataBase* pDevDataRob = (CDevDataBase*)m_pRobDev->m_pDevDataBase;
	pDevDataRob->m_nBelogn = m_pRBasicDataNd->m_pTaskExecInfo->m_vecPolItemCom[m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount]->m_pPolItem->m_nBelong;
	pDevDataRob->m_dDetecOffset= m_pRBasicDataNd->m_pTaskExecInfo->m_vecPolItemCom[m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount]->m_pPolItem->m_dRollerOffdetDis;
	m_pRBasicDataNd->m_pTaskExecInfo->m_vecPolItemCom[m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount]->m_bIsAction = true;
	m_pRBasicDataNd->m_pTaskExecInfo->m_nExecItemCount++;
	updateTaskExecInfo(m_pRBasicDataNd->m_pTaskExecInfo);
	insertItemExecResult(m_pRBasicDataNd->m_pTaskExecInfo);//addwxy
	m_pRBasicDataNd->m_pMutex->unlock();
	setEvent(enJUDGE);
}

void CWorkMngAutoHy::taskSleep(int nSleep)
{
	resetEvent(enSLEEP);
	static int nSleepIndex = 0;
	if (nSleepIndex < nSleep)
	{
		nSleepIndex++;
		setEvent(enSLEEP);
	}
	else
	{
		nSleepIndex = 0;
		setEvent(enSCANTASK);
	}
}


void CWorkMngAutoHy::_workRun()
{
	//计数  5秒去扫描一次任务扫描任务
	int nTimeIndex = 0;
	int nEvent = 0;
	setEvent(enSCANTASK);
	m_pRBasicDataNd->m_pMutex->lock();
	CTaskExecInfo *pTaskExecInfo = m_pRBasicDataNd->m_pTaskExecInfo;
	CDevDataBase* pDevData = (CDevDataBase*)m_pRobDev->m_pDevDataBase;
	//新任务插入数据库之前,把数据库中异常处于状态2执行中的任务置为状态3终止
	//CSqlOperRob::instance().dealTaskExecErrState(m_sGuid, pDevData->m_sRobBatteryInfo.get().toInt());
	m_pRBasicDataNd->m_pMutex->unlock();
	while (m_bThreadStart)
	{

		/**
		* @ Author: Gaojia
		* @ Description:  5秒钟扫描一次任务数组
		*/
		{
			if (nTimeIndex == 100)
			{
				refreshTaskInfo();
				//qDebug() << QDateTime::currentDateTime().toString() << endl;
				nTimeIndex = 0;
			}
			if (nEvent != enPROCESS)
			{
				nTimeIndex++;

			}

		}
		/**
		* @ Author: Gaojia
		* @ Description:
		* 配置中 不执行任务
		* 遥控模式不执行任务
		*/
		if (m_pRobDev->m_pDevDataBase->m_nRobRunMode != 1)
		{
			sysSleepTime(50);
			continue;
		}
		
		/**
		* @ Author: Gaojia
		* @ Description: 判断急停是否被按下
		急停按下不执行任务
		*/
		if (pDevData->m_bSuddenStop == true)
		{
			sysSleepTime(50);
			continue;
		}
		/**
		* @ Author: Gaojia
		* @ Description:
		*  扫描任务的时候 判断电量 低于阈值不执行任务
		*/
		if (nEvent == enSCANTASK)
		{
			pDevData->m_pMutex->lock();
			if (pDevData->m_sRobBatteryInfo.toDouble() <= pDevData->m_dTaskEleQuantityThreshold ||
				pDevData->m_sBatteryVol.toDouble() <= pDevData->m_dTaskEleQuantityVoltage)
			{
				sysSleepTime(50);
				pDevData->m_pMutex->unlock();
				continue;
			}
			pDevData->m_pMutex->unlock();
		}
		m_bAddLog = true;
		nEvent = waitForObjects();
		switch (nEvent)
		{
		case enSHUTDOWN:        //停止
		{
			resetEvent();
			sysSleepTime(50);
			break;
		}
		case enSUSPENDTASK:     //暂停任务
		{
			//复位所有线程
			resetEvent();
			taskSuspend();
			sysSleepTime(50);
			break;
		}
		case enRESETTASK:       //恢复任务
		{
			//复位所有线程
			resetEvent();
			taskReset();
			sysSleepTime(50);
			break;
		}
		case enEXECENDTASK:     //结束任务
		{
			resetEvent();
			insertCotDetRet();//插入连续检测结果
			taskStop();
			m_pRobDev->m_pDevDataBase->m_bTaskExec = false;
			sysSleepTime(50);
			break;
		}
		case enPROCESS:         //执行任务
		{
			//复位执行任务事件
			resetEvent(enPROCESS);
			taskProcess();
			sysSleepTime(10);
			break;
		}
		case enJUDGE:           //判断 流程
		{
			//复位扫描事件
			resetEvent(enJUDGE);
			taskJudge();
			sysSleepTime(50);
			break;
		}
		case enEXCEPTION:       //设备异常
		{
			//复位异常事件
			resetEvent(enEXCEPTION);
			taskExceptoin();
			sysSleepTime(50);
			break;
		}
		case enSCANTASK:        //扫描任务
		{
			resetEvent(enSCANTASK);
			taskScan();
			sysSleepTime(50);
			break;
		}
		case enSLEEP:        //线程休眠等待
		{
			taskSleep(240);
			sysSleepTime(50);
			break;
		}
		default:
			sysSleepTime(50);
			break;
		}

	}
}

void CWorkMngAutoHy::refreshTaskInfo()
{

	/**
	* @ Author: Gaojia
	* @ Description: 获取皮带状态
	*/
	QString sMas = "";
	int nDate = 0;
	//int nDate = CSqlOperPub::instance().selectBeltWork(m_sGuid, sMas);
	if (nDate == 0)
	{
		m_bBeltAWork = false;
		m_bBeltBWork = false;
		m_nBeltWorkCount = 0;
	}
	else if (nDate == 1)
	{
		if (m_nBeltWorkCount > 3)
		{
			m_nBeltWorkCount = 0;
			m_bBeltAWork = true;
			m_bBeltBWork = false;
		}
		m_nBeltWorkCount++;
	}
	else if (nDate == 2)
	{
		if (m_nBeltWorkCount > 3)
		{
			m_nBeltWorkCount = 0;
			m_bBeltAWork = false;
			m_bBeltBWork = true;
		}
		m_nBeltWorkCount++;
	}
	CDevDataBase* pDevData = (CDevDataBase*)m_pRobDev->m_pDevDataBase;
	pDevData->m_bBeltAWork = m_bBeltAWork;
	pDevData->m_bBeltBWork = m_bBeltBWork;
	/**
	* @ Author: Gaojia
	* @ Description:  1.判断数组里面有没有过期的任务
	*/
	for (int i = 0; i < m_vecTaskInfo.size(); i++)
	{
		if (compareTimeOverdue(m_vecTaskInfo[i].m_sTaskActTime))
		{
			if (m_bAddLog)
			{
				pDevData->m_pMutex->lock();
				QString sData = "";
				if (m_pRobDev->m_pDevDataBase->m_nRobRunMode != 1)
				{
					sData = A2T("机器人不在任务模式。");

				}
				else if (pDevData->m_bSuddenStop == true)
				{
					sData = A2T("机器人急停被按下。");
				}
				else if (pDevData->m_sRobBatteryInfo.toDouble() <= pDevData->m_dTaskEleQuantityThreshold)
				{

					sData = A2T("电量低于阈值，不执行任务。") + pDevData->m_sRobBatteryInfo + "---" + QString::number(pDevData->m_dTaskEleQuantityThreshold);				
				}
				else
				{
					sData = A2T("其他原因");
				}
				pDevData->m_pMutex->unlock();
				//记录日志
				SExecLog sLog;
				sLog.m_nAlarmLevel = enProcessAlarm;
				sLog.m_sDescriptionl = A2T("任务到时不执行，%1").arg(sData);
				sLog.m_sFuncName = A2T("任务");
				CLogOper::instance().addMsg(sLog, m_sGuid);
				m_bAddLog = false;
			}
			insertTaskExecInfoEx(m_vecTaskInfo[i]);	
		}
	}
	m_vecTaskInfo.clear();
	/**
	* @ Author: Gaojia
	* @ Description:  2.清空数组 生成 所有当前时间之后的待执行任务
	*/
	QString sErrMsg = "";
	QMap<QString, CTaskInfo>mapTaskInfo;       //数据任务类别
	QVector<CTaskInfo>vecTaskInfo = selectTaskInfoEx(m_sGuid, sErrMsg);
	for (int i = 0; i < vecTaskInfo.size(); i++)
	{
		if (vecTaskInfo[i].m_nTaskType == 1)
		{
			mapTaskInfo.insert(vecTaskInfo[i].m_sTaskGuid, vecTaskInfo[i]);
		}
		else if (vecTaskInfo[i].m_nTaskType == 0)
		{
			if (compareTime(vecTaskInfo[i].m_sScheduledTime))
			{
				vecTaskInfo[i].m_sTaskActTime = vecTaskInfo[i].m_sScheduledTime;
				m_vecTaskInfo.push_back(vecTaskInfo[i]);
			}
		}
		else if (vecTaskInfo[i].m_nTaskType == 2)
		{
			if (compareTime(vecTaskInfo[i].m_sScheduledTime, 1))
			{
				m_vecTaskInfo.push_back(vecTaskInfo[i]);
			}
		}
		else if (vecTaskInfo[i].m_nTaskType == 3)
		{
			if (m_bBeltAWork && !m_pRobDev->m_pDevDataBase->m_bTaskExec&&m_pRobDev->m_pDevDataBase->m_nRobRunMode == 1)
			{
				if (m_bAddLog)
				{
					vecTaskInfo[i].m_sTaskActTime = QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss");
					m_vecTaskInfo.push_back(vecTaskInfo[i]);
				}

			}
		}
		else if (vecTaskInfo[i].m_nTaskType == 4)
		{
			if (m_bBeltBWork && !m_pRobDev->m_pDevDataBase->m_bTaskExec&&m_pRobDev->m_pDevDataBase->m_nRobRunMode == 1)
			{
				if (m_bAddLog)
				{
					vecTaskInfo[i].m_sTaskActTime = QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss");
					m_vecTaskInfo.push_back(vecTaskInfo[i]);
				}
			}
		}
	}
	QMap<int, QString>mapTaskGiud = selectTaskRule(m_sGuid, sErrMsg);
	for (QMap<int, QString>::iterator i = mapTaskGiud.begin(); i != mapTaskGiud.end(); i++)
	{
		if (mapTaskInfo.contains(i.value()))
		{
			QString sReTime = "";
			if (compareTimeEx(i.key(), sReTime))
			{
				CTaskInfo cTaskInfo = mapTaskInfo[i.value()];
				cTaskInfo.m_sTaskActTime = sReTime;
				m_vecTaskInfo.push_back(cTaskInfo);
			}
		}
	}

	m_pRBasicDataNd->m_pMutex->lock();
	m_pRBasicDataNd->m_vecTaskInfo = m_vecTaskInfo;
	m_pRBasicDataNd->m_pMutex->unlock();

	/**
	* @ Author: Gaojia
	* @ Description:  3.查询任务记录表里面所有的任务记录
	*/
	QVector<CTaskExecInfo>vecTaskExecInfo;
	QVector<QSqlRecord> vecRecord;
	selCurrTaskExecByID(m_sGuid, vecRecord, sErrMsg);
	for (int i = 0; i < vecRecord.size(); i++)
	{
		CTaskExecInfo uInfo;
		uInfo.m_sTaskExecGuid = vecRecord[i].value("GUID").toString();
		uInfo.m_sTaskName = vecRecord[i].value("TASK_NAME").toString();
		uInfo.m_sTemplateGuid = vecRecord[i].value("TEMPLATE_GUID").toString();
		uInfo.m_sGuid = m_sGuid;
		uInfo.m_nExecState = vecRecord[i].value("EXEC_STATUS").toInt();
		uInfo.m_nItemCount = vecRecord[i].value("ITEM_COUNT").toInt();
		uInfo.m_nExecItemCount = vecRecord[i].value("EXEC_ITEM_COUNT").toInt();
		uInfo.m_nAlarmItemCount = vecRecord[i].value("ALARM_ITEM_COUNT").toInt();
		uInfo.m_sStartTime = vecRecord[i].value("START_TIME").toDateTime().toString("yyyy/MM/dd hh:mm:ss");
		uInfo.m_sEndTime = vecRecord[i].value("END_TIME").toDateTime().toString("yyyy/MM/dd hh:mm:ss");
		uInfo.m_dStartPower = vecRecord[i].value("START_POWER").toDouble();
		uInfo.m_dEndPower = vecRecord[i].value("END_POWER").toDouble();
		uInfo.m_dEndPower = vecRecord[i].value("END_POWER").toDouble();
		uInfo.m_nCollectAlarmCount= vecRecord[i].value("COLLECT_ALARM_COUNT").toInt();
		vecTaskExecInfo.push_back(uInfo);
	};

	m_pRBasicDataNd->m_pMutex->lock();
	m_pRBasicDataNd->m_vecTaskExecInfo = vecTaskExecInfo;
	m_pRBasicDataNd->m_pMutex->unlock();

}

/**
* @ Author: Gaojia
* @ Description:  执行巡检项
*/
bool CWorkMngAutoHy::execItem()
{
	SCtrInfo stCtrInfo;
	m_pRBasicDataNd->m_pMutex->lock();
	CTaskExecInfo *pTaskExecInfo = m_pRBasicDataNd->m_pTaskExecInfo;
	stCtrInfo.m_sGuid = m_sGuid;
	stCtrInfo.m_bCtrSync = true;
	stCtrInfo.m_bHasCtr = false;
	stCtrInfo.m_pPolItemCom = pTaskExecInfo->m_vecPolItemCom[pTaskExecInfo->m_nExecItemCount];
	stCtrInfo.m_nCtrDevType = stCtrInfo.m_pPolItemCom->m_pPolItem->m_nDevType;
	stCtrInfo.m_nCtrCmd = enCExecItemCamer;//addwxy
	if (stCtrInfo.m_nCtrDevType == 1)
	{
		if (m_pRobDev->ctrDev(stCtrInfo))
		{
			m_pRBasicDataNd->m_pMutex->unlock();
			return true;
		}
		else
		{
			m_pRBasicDataNd->m_pMutex->unlock();
			return true;
		}
	}
	else
	{
		m_pRBasicDataNd->m_pMutex->unlock();
		return true;
	}
}

/**
* @ Author: WeiXiaoYu
* @ Description:  执行算法
*/
bool CWorkMngAutoHy::execAlgorithm()
{
	if (m_pRBasicDataNd == nullptr)
	{
		return false;
	}
	m_pRBasicDataNd->m_pMutex->lock();
	CTaskExecInfo *pTaskExecInfo = m_pRBasicDataNd->m_pTaskExecInfo;
	QString sTaskName = pTaskExecInfo->m_sTaskName;
	if (pTaskExecInfo == nullptr)
	{
		return false;
	}
	SCPolItemCom *pPolItemCom = pTaskExecInfo->m_vecPolItemCom[pTaskExecInfo->m_nExecItemCount];//取出来
	if (pPolItemCom == nullptr)
	{
		return false;
	}
	m_pRBasicDataNd->m_pMutex->unlock();
	if (m_pAlgorithmContext != nullptr)
	{
		return m_pAlgorithmContext->actionAlgorthm(pPolItemCom, sTaskName);//算法处理
	}

	return false;
}


//打开对讲
void CWorkMngAutoHy::startTalkBack()
{
	if (m_pRobDev == nullptr)
	{
		return;
	}

	SCtrInfo stCtrInfo;
	stCtrInfo.m_sGuid = m_sGuid;
	stCtrInfo.m_bCtrSync = true;
	stCtrInfo.m_bHasCtr = false;
	stCtrInfo.m_nCtrDevType = enSubDev1;
	stCtrInfo.m_nCtrCmd = ECCamerCmdType::enCVoiceTalk;
	m_pRobDev->ctrDev(stCtrInfo);
}
//停止对讲
void CWorkMngAutoHy::stopTalkBack()
{
	if (m_pRobDev == nullptr)
	{
		return;
	}
	SCtrInfo stCtrInfo;
	stCtrInfo.m_sGuid = m_sGuid;
	stCtrInfo.m_bCtrSync = true;
	stCtrInfo.m_bHasCtr = false;
	stCtrInfo.m_nCtrDevType = enSubDev1;
	stCtrInfo.m_nCtrCmd = ECCamerCmdType::enCStopVoiceTalk;
	m_pRobDev->ctrDev(stCtrInfo);
}

bool CWorkMngAutoHy::selectCycTask()
{
	QDateTime dDataStart = QDateTime::currentDateTime().addSecs(-3600);
	QDateTime dDataEnd = QDateTime::currentDateTime().addSecs(3600);
	int nStart = dDataStart.time().hour() * 2 + dDataStart.time().minute() / 30;
	int nEnd = dDataEnd.time().hour() * 2 + dDataEnd.time().minute() / 30;
	QVector<int> vecTimePoints;
	for (int i = nStart; i <= nEnd; ++i)
	{
		vecTimePoints.append(i);
	}

	//根据得到的时间枚举查看座位并将查到的任务Guid存到一个vector中
	QVector<QString> vecTaskGuid;//任务guid
	{
		QVector<QSqlRecord> vecRecord;
		QString sErrMsg = "";
		bool bRet = selTaskRuleByTimeType(m_sGuid, vecTimePoints, vecRecord, sErrMsg);
		if (bRet)
		{
			for (int i = 0; i < vecRecord.size(); i++)
			{
				QString sTaskGuid = vecRecord[i].value("TASK_GUID").toString();
				if (sTaskGuid != "")
				{
					if (!vecTaskGuid.contains(sTaskGuid))
					{
						vecTaskGuid.push_back(sTaskGuid);
					}
				}
				continue;
			}
		}
	}

	//根据任务Guid获取任务配置表
	if (vecTaskGuid.size() > 0)
	{
		QString sErrMsg = "";
		m_vecTaskInfo.append(selTaskInfoByTaskID(m_sGuid, vecTaskGuid, sErrMsg));
	}
	return true;
}

//插入连续检测结果
bool CWorkMngAutoHy::insertCotDetRet()
{
	if (m_pAlgorithmContext != nullptr)
	{
		m_pAlgorithmContext->closeCotDet();//关闭所有连续检测
	}
	return true;
}


void CWorkMngAutoHy::timerEvent(QTimerEvent * event)
{
	if (event->timerId() == m_nRefushTaskTimer)
	{
		refreshTaskInfo();
	}
}
